package gspushmq.v1.produce.job.sys;

import com.alibaba.fastjson.JSON;
import ggframework.mongodb.BasicDBObject;
import ggframework.mongodb.DBCollection;
import ggframework.mongodb.DBCursor;
import ggframework.mongodb.DBObject;
import gspushmq.model.*;
import gspushmq.util.DateUtil;
import gspushmq.util.GGLogger;
import gspushmq.util.MongoUtil;
import gspushmq.util.SysUtil;
import gspushmq.v1.app.producerapp.AppInterface;
import gspushmq.v1.app.subscribeapp.api.PushHelper;
import gspushmq.v1.app.subscribeapp.enumeration.ProducerEnum;
import gspushmq.v1.app.subscribeapp.enumeration.PushTypeEnum;
import gspushmq.v1.app.subscribeapp.enumeration.TagEnum;
import gspushmq.v1.app.subscribeapp.models.BaseVO;
import gspushmq.v1.consumer.core.MessageQueue;
import gspushmq.v1.produce.job.core.GGServiceJob;
import sun.util.calendar.BaseCalendar;

import java.util.Date;
import java.util.Map;


/**
 *
 * @description pc端vip实战股票池（1分钟生产一次）
 * @param
 * @version 1.0
 * @author chengsja
 * @date 2018/12/20 16:14
 *
 */
public class GGVipStockInOutJob extends GGServiceJob implements AppInterface {

    private static DBCollection collection;

    private static Date lastDate;

    private static String fileName = "./cache/" + PrefixEnum.STOCK_VIP.getMqSubType() + ".txt";


    @Override
    protected String setJobName() {
        return PrefixEnum.STOCK_VIP.getMqName();
    }

    @Override
    protected void before() {
        collection = MongoUtil.getGGStockCollection("ggzt_stock_pool");
    }

    @Override
    public void doServiceJob(Map<String, Object> args) {

        try {
            lastDate = SysUtil.getCacheLastDate(fileName);
        } catch (Exception e) {
            GGLogger.info(this.getClass(), "本次读取错误，不生产消息！" + e.getMessage());
            return;
        }
        DBCursor cursor = collection.find(new BasicDBObject("update_time", new BasicDBObject("$gt", lastDate))
        .append("status", new BasicDBObject("$ne",0))).sort(new BasicDBObject("update_time", -1));
        Date temp = null;
        while (cursor.hasNext()) {
            DBObject o = cursor.next();

            if (temp == null) {
                //记录最新时间
                temp = o.getDate("update_time");
            }
            DataMessage dm = new DataMessage();
            dm.setMqType(PrefixEnum.STOCK_VIP.getMqType());
            dm.setMqSubType(PrefixEnum.STOCK_VIP.getMqSubType());
            dm.setUserType(UserType.ASSIGN);
            dm.setCrowdType(ConsumerWays.TAG.getWay());
            //5
            dm.setCrowdValue(VersionEnum.getNumber(28, 5).toString());
            dm.setProductLine(28);
            dm.setTitle("vip实战股票池变动提醒");
            //内链
            dm.setLinkType(LinkEnum.INNER.getLinkType());
            //模块id
            dm.setModule(SkipConstant.STOCK_VIP_MODULE);
            //目标id
            dm.setTarget(o.getString("stock_code"));
            //消息过期时间1min
            dm.setExpireDate(DateUtil.getAddMinute(o.getDate("update_time"), 1));
            dm.setStartDate(o.getDate("update_time"));
            try {
                String content = new StringBuffer(o.getString("stock_name")).append(o.getString("stock_code")).append(tail(o)).toString();
                dm.setContent(content);
                //app需要判断跳转页面，status=1表示调入，进入实战股票池页面，2表示调出，进入历史股票池页面
                dm.setParams(o.getString("status"));
                //入web队列
                MessageQueue.messageQueue.add(dm);
                //入app消息池
                sendToApp(o);
            } catch (Exception e) {
                GGLogger.error(this.getClass(), "异常生产/异常为：" + e.getMessage());
            }
            //入库
            SysUtil.sendToMongo(dm);
            //日志
            SysUtil.logPattern(GGVipStockInOutJob.class,dm);
        }
        cursor.close();
        try {
            SysUtil.cacheTimeSwapToFile(temp == null ? new Date() : temp, fileName);
        } catch (Exception e) {
            e.printStackTrace();
            GGLogger.info(this.getClass(), "更新入缓存时间异常:" + e.getMessage());
        }
    }

    /**
     * 拼接业务消息体
     * {
     * status 1:调入 2.调出
     * event  longest_term:达到最长期限 ， target_profit:达到目标收益,  price_stop：达到止损线
     * pushtype  manual：手动调出，automatic：自动调出
     * }
     * Created by chengsj on 2018/11/8
     */
    private static String tail(DBObject o) throws Exception {
        if (o == null) {
            throw new Exception("基础消息对象不能为null");
        }
        Integer status = o.getInteger("status");
        if (status == null) {
            throw new Exception("生产消息/拼接消息体时调入状态异常! status=null");
        }
        StringBuffer buffer = new StringBuffer();
        if (1 == status) {
            buffer.append("新入选到实战股票池");
        }
        if (2 == status) {
            String event = o.getString("call_out");
            String pushtype = o.getString("push_type");
            //手动调出
            if ("manual".equals(pushtype)) {
                buffer.append("调出实战股票池,调出收益").append(changeNumToPercent(o.getDouble("out_rate"),1)).append("。");
            } else { //自动调出
                if ("price_stop".equals(event)) {
                    buffer.append("触及止损线").append(changeNumToPercent(o.getDouble("price_stop"),0)).append(",系统自动调出。");
                }
                if ("target_profit".equals(event)) {
                    buffer.append("调出实战股票池,调出收益").append(changeNumToPercent(o.getDouble("target_profit"),0)).append("。");
                }
                if ("longest_term".equals(event)) {
                    buffer.append("到达最长期限,系统自动调出。");
                }
            }
        }
        return buffer.toString();
    }

    /**
     *
     * @description 百分比换算
     * @param   type 1：需要乘100%，否则不用
     * @version 1.0
     * @author chengsja
     * @date 2018/12/25 10:02
     *
     */
    private static String changeNumToPercent(Double d,int type) throws Exception {
        if (d == null) {
            throw new Exception("转换百分比异常：value=null");
        }
        String tem = String.valueOf(d);
        if (type == 1) {
            //乘100%，2位小数
            tem = String.format("%.2f",d*100);
        }
        return d >= 0 ? "+" + tem + "%" : tem + "%";
    }






    @Override
    public boolean sendToApp(DBObject object) throws Exception{
        if (object == null){
            return false;
        }
        BaseVO vo = new BaseVO();
        //第三方平台
        vo.setPlate_code(9001);
        //app产品线
        vo.setSource(appProductLine);
        //系统消息
        vo.setProducer_code(ProducerEnum.GG_BACK.getCode());
//        消费者6701Android，6702是iOS
//        vo.setConsumer_code(6701);
        //标题
        vo.setMessage_title("vip实战股票池变动提醒");
        //内容
        vo.setMessage_content(new StringBuffer(object.getString("stock_name")).append(object.getString("stock_code")).append(tail(object)).toString());
        //开始推送时间
        vo.setStart_time(new Date());
        //过期时间,12小时
        vo.setEnd_time(DateUtil.getAddMinute(new Date(), 12*60));
        //内链
        vo.setNotice_link_type(gspushmq.v1.app.subscribeapp.enumeration.LinkEnum.INNER.getCode());
        //内链具体股票简码
        vo.setNotice_goto_id(vipApiParams(object.getInteger("status"),object.getString("stock_code"),object.getString("_id")));
        //内链模块id
        vo.setNotice_ext_parameters("VipStockPool");
        //内链模块名称
        vo.setNotice_goto_name("VIP实战股票池模块");
        //群组推送方式
        vo.setTarget_code(PushTypeEnum.GROUP.getCode());
        //首席版用户
        vo.setLevels(String.valueOf(TagEnum.GZ_CHIEF.getCode()));
        vo.setAuther("admin");
        try {
            PushHelper.pushApp(vo);
            GGLogger.info(GGVipStockInOutJob.class,"---------vip实战股票池投递app端成功!----------"+JSON.toJSONString(vo));
            return true;
        }catch (Exception e){
            GGLogger.error(GGVipStockInOutJob.class,"---------vip实战股票池投递app端失败!----------"+e);
            return false;
        }
    }


    /**
     * 拼接vip实战股票池stockId字段
     * 跳转页面&股票简码&股票唯一操作标识
     * 例如： vip_stock_pool_in&902345&123
     *
     * @retrun
     * @author chengsj 2019/2/26
     *
     */
    private static String vipApiParams(Integer status,String code,String id){
        return vipPage(status) + code + "&"+id;
    }

    /**
    *
    * 根据调入调出状态值，拼接vip跳转页面，1：调入，2调出
    */
    private static String vipPage(Integer status){
        if (1 == status){
            return "vip_stock_pool_in&";
        }else if (2 == status){
            return "vip_stock_pool_out&";
        }else {
            GGLogger.error(GGVipStockInOutJob.class,"vip实战股票池股票调入调出状态获取失败！");
            return "vip_stock_pool_erro&";
        }
    }
}
